package com.rnkrsoft.suyan.config.server.services.impl;


import com.rnkrsoft.framework.orm.Pagination;
import com.rnkrsoft.suyan.config.internal.enums.*;
import com.rnkrsoft.suyan.config.protocol.v2.ConfigResponseCode;
import com.rnkrsoft.suyan.config.protocol.v2.DataTypeEnum;
import com.rnkrsoft.suyan.config.server.config.dao.*;
import com.rnkrsoft.suyan.config.server.config.bo.*;
import com.rnkrsoft.suyan.config.server.config.entity.*;
import com.rnkrsoft.suyan.config.server.services.authority.domains.AuthorityUser;
import com.rnkrsoft.suyan.config.server.services.logger.services.LoggerService;
import com.rnkrsoft.suyan.config.server.services.param.domains.*;
import com.rnkrsoft.suyan.config.server.services.param.services.ParamService;
import com.rnkrsoft.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by woate on 2018/6/19.
 */
@Service
public class ParamServiceImpl implements ParamService {
    @Autowired
    ProjectInfoDAO projectDAO;
    @Autowired
    ProjectDependencyDAO projectDependencyDAO;
    @Autowired
    VersionInfoDAO versionInfoDAO;
    @Autowired
    EnvironmentInfoDAO environmentDAO;
    @Autowired
    MachineInfoDAO machineDAO;
    @Autowired
    ParamInfoDAO paramDAO;
    @Autowired
    AuthorityInfoDAO authorityDAO;
    @Autowired
    LoggerService loggerService;

    @Override
    public ToUpdateParamResponse toUpdate(ToUpdateParamRequest request) {
        ToUpdateParamResponse response = new ToUpdateParamResponse();
        ParamInfoEntity paramEntity = paramDAO.selectByPrimaryKey(request.getParamId());
        if (paramEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        //查询当前用户是否拥有权限
        int hasAuthority = authorityDAO.countAnd(AuthorityInfoEntity.builder()
                .resourceType(ResourceTypeEnum.PARAM.getCode())
                .resourceId(paramEntity.getParamId())
                .userId(request.getLoginUserId())
                .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                .build());
        if (hasAuthority == 0) {
            response.updateResult(ConfigResponseCode.NOT_AUTHORITY);
            return response;
        }
        if (YesOrNo.valueOfCode(paramEntity.getParamExtends()) == YesOrNo.Y) {
            response.updateResult(ConfigResponseCode.NO_DATA.getCode(), "继承参数，不能在当前项目编辑");
            return response;
        }
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(paramEntity.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        EnvironmentInfoEntity environmentEntity = environmentDAO.selectByPrimaryKey(machineEntity.getEnvironmentId());
        if (environmentEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        VersionInfoEntity versionInfoEntity = versionInfoDAO.selectByPrimaryKey(environmentEntity.getVersionId());
        if (versionInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        ProjectInfoEntity projectInfoEntity = projectDAO.selectByPrimaryKey(versionInfoEntity.getProjectId());
        if (projectInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }

        response.setProject(projectInfoEntity.getProjectDesc() + "(" + projectInfoEntity.getGroupId() + ":" + projectInfoEntity.getArtifactId() + ")");
        response.setEnvironment(environmentEntity.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(environmentEntity.getEnvironmentType()).getDesc() + ")");
        response.setMachine(machineEntity.getMachineName());
        response.setParamId(paramEntity.getParamId());
        response.setParamName(paramEntity.getParamName());
        String paramValue = paramEntity.getParamValue();
        response.setParamValue(paramValue);
        response.setParamDataType(paramEntity.getParamDataType());
        response.setParamType(paramEntity.getParamType());
        response.setParamVersion(paramEntity.getParamVersion());
        response.setParamDynamic(paramEntity.getParamDynamic());
        response.setParamEncrypt(paramEntity.getParamEncrypt());
        response.setSystemProperties(paramEntity.getParamSystemProperties());
        response.setParamStatus(paramEntity.getParamStatus());
        response.setParamDesc(paramEntity.getParamDesc());

        List<AuthorityInfoEntity> authorityInfoEntities = authorityDAO.selectAnd(AuthorityInfoEntity.builder()
                        .resourceType(ResourceTypeEnum.PARAM.getCode())
                        .resourceId(paramEntity.getParamId())
                        .userId(request.getLoginUserId())
                        .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                        .build()
        );
        for (AuthorityInfoEntity authorityInfoEntity : authorityInfoEntities) {
            response.getAuthorityUsers().add(AuthorityUser.builder().userId(authorityInfoEntity.getUserId()).userName(authorityInfoEntity.getUserName()).build());
        }
        return response;
    }

    @Override
    public UpdateParamResponse update(UpdateParamRequest request) {
        UpdateParamResponse response = new UpdateParamResponse();
        ParamInfoEntity paramEntity = paramDAO.selectByPrimaryKey(request.getParamId());
        if (paramEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        if (YesOrNo.valueOfCode(paramEntity.getParamExtends()) == YesOrNo.Y) {
            response.updateResult(ConfigResponseCode.NO_DATA.getCode(), "继承参数，不能在当前项目编辑，需要到抽象项目进行编辑");
            return response;
        }
        //查询当前用户是否拥有权限
        int hasAuthority = authorityDAO.countAnd(AuthorityInfoEntity.builder()
                .resourceType(ResourceTypeEnum.PARAM.getCode())
                .resourceId(paramEntity.getParamId())
                .userId(request.getLoginUserId())
                .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                .build());
        if (hasAuthority == 0) {
            response.updateResult(ConfigResponseCode.NOT_AUTHORITY);
            return response;
        }
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(paramEntity.getMachineId());
        String paramValue = request.getParamValue();
        DataTypeEnum dataTypeEnum = DataTypeEnum.valueOfCode(request.getParamDataType());
        if (dataTypeEnum == DataTypeEnum.BOOLEAN) {
            if (!"true".equals(paramValue) && !"false".equals(paramValue)) {
                response.updateResult(ConfigResponseCode.FAIL.getCode(),"参数类型为布尔值，请输入true/false");
                return response;
            }
        } else if (dataTypeEnum == DataTypeEnum.INTEGER) {
            if (!paramValue.matches("^\\d+$")) {
                response.updateResult(ConfigResponseCode.FAIL.getCode(),"参数类型为整数值，请输入有效的整数值");
                return response;
            }

            if (Integer.valueOf(paramValue) < Integer.MIN_VALUE || Integer.valueOf(paramValue) > Integer.MAX_VALUE) {
                response.updateResult(ConfigResponseCode.FAIL.getCode(),"参数类型为整数值，数据越界");
                return response;
            }
        }
        paramEntity.setParamName(request.getParamName());
        paramEntity.setParamValue(paramValue);
        paramEntity.setParamDataType(request.getParamDataType());
        paramEntity.setParamType(request.getParamType());
        paramEntity.setParamVersion(paramEntity.getParamVersion() + 1);
        paramEntity.setParamDynamic(request.getParamDynamic());
        paramEntity.setParamEncrypt(request.getParamEncrypt());
        paramEntity.setParamSystemProperties(request.getSystemProperties());
        paramEntity.setParamStatus(request.getParamStatus());
        paramEntity.setParamDesc(request.getParamDesc());
        paramEntity.setParamLastUpdater(request.getLoginUserId());

        loggerService.writeLog(OperateObjectEnum.PARAM, paramEntity.getParamId(), OperateTypeEnum.UPDATE, request.getLoginUserId(), request.getLoginUserName());

        paramDAO.updateByPrimaryKeySelective(paramEntity);
        System.out.println(request.getAuthorityUsers());
        //刷新机器的更新时间
        machineDAO.updateByPrimaryKeySelective(machineEntity);
        return response;
    }

    @Override
    public DeleteParamResponse delete(DeleteParamRequest request) {
        DeleteParamResponse response = new DeleteParamResponse();
        ParamInfoEntity paramEntity = paramDAO.selectByPrimaryKey(request.getParamId());
        if (paramEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        //查询当前用户是否拥有权限
        int hasAuthority = authorityDAO.countAnd(AuthorityInfoEntity.builder()
                .resourceType(ResourceTypeEnum.PARAM.getCode())
                .resourceId(paramEntity.getParamId())
                .userId(request.getLoginUserId())
                .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                .build());
        if (hasAuthority == 0) {
            response.updateResult(ConfigResponseCode.NOT_AUTHORITY);
            return response;
        }
        loggerService.writeLog(OperateObjectEnum.PARAM, paramEntity.getParamId(), OperateTypeEnum.DELETE, request.getLoginUserId(), request.getLoginUserName());

        paramDAO.deleteByPrimaryKey(request.getParamId());
        MachineInfoEntity machineInfoEntity = machineDAO.selectByPrimaryKey(paramEntity.getMachineId());
        //刷新机器的更新时间
        machineDAO.updateByPrimaryKeySelective(machineInfoEntity);
        return response;
    }

    @Override
    public ViewParamResponse view(ViewParamRequest request) {
        ViewParamResponse response = new ViewParamResponse();
        ParamInfoEntity paramEntity = paramDAO.selectByPrimaryKey(request.getParamId());
        if (paramEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(paramEntity.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        EnvironmentInfoEntity environmentEntity = environmentDAO.selectByPrimaryKey(machineEntity.getEnvironmentId());
        if (environmentEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        VersionInfoEntity versionInfoEntity = versionInfoDAO.selectByPrimaryKey(environmentEntity.getVersionId());
        if (versionInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        ProjectInfoEntity projectInfoEntity = projectDAO.selectByPrimaryKey(versionInfoEntity.getProjectId());
        if (projectInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        //查询当前用户是否拥有权限
        int hasAuthority = authorityDAO.countAnd(AuthorityInfoEntity.builder()
                .resourceType(ResourceTypeEnum.PARAM.getCode())
                .resourceId(paramEntity.getParamId())
                .userId(request.getLoginUserId())
                .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                .build());

        response.setProject(projectInfoEntity.getProjectDesc() + "(" + projectInfoEntity.getGroupId() + ":" + projectInfoEntity.getArtifactId() + ")");
        response.setEnvironment(environmentEntity.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(environmentEntity.getEnvironmentType()).getDesc() + ")");
        response.setMachine(machineEntity.getMachineName());
        response.setParamId(paramEntity.getParamId());
        response.setParamName(paramEntity.getParamName());
        String paramValue = null;
        if (hasAuthority > 0) {
            paramValue = paramEntity.getParamValue();
        } else {
            paramValue = "您当前无权限查看！";
        }
        response.setParamValue(paramValue);
        response.setParamDataType(paramEntity.getParamDataType());
        response.setParamType(paramEntity.getParamType());
        response.setParamVersion(paramEntity.getParamVersion());
        response.setParamDynamic(paramEntity.getParamDynamic());
        response.setParamEncrypt(paramEntity.getParamEncrypt());
        response.setSystemProperties(paramEntity.getParamSystemProperties());
        response.setParamStatus(paramEntity.getParamStatus());
        response.setParamDesc(paramEntity.getParamDesc());

        List<AuthorityInfoEntity> authorityInfoEntities = authorityDAO.selectAnd(AuthorityInfoEntity.builder()
                        .resourceType(ResourceTypeEnum.PARAM.getCode())
                        .resourceId(paramEntity.getParamId())
                        .userId(request.getLoginUserId())
                        .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                        .build()
        );
        for (AuthorityInfoEntity authorityInfoEntity : authorityInfoEntities) {
            response.getAuthorityUsers().add(AuthorityUser.builder().userId(authorityInfoEntity.getUserId()).userName(authorityInfoEntity.getUserName()).build());
        }
        return response;
    }

    @Override
    public QueryParamResponse query(QueryParamRequest request) {
        QueryParamResponse response = new QueryParamResponse();
        Pagination<QueryParamInfoBO> pagination = new Pagination<QueryParamInfoBO>(request.getPagination().getPageSize(), request.getPagination().getPageNo());
        if (StringUtils.isNotBlank(request.getProjectId())) {
            pagination.getParams().put("projectId", request.getProjectId());
        }
        if (StringUtils.isNotBlank(request.getEnvironmentName())) {
            pagination.getParams().put("environmentName", request.getEnvironmentName());
        }
        if (StringUtils.isNotBlank(request.getEnvironmentType())) {
            pagination.getParams().put("environmentType", request.getEnvironmentType());
        }
        if (StringUtils.isNotBlank(request.getMachineName())) {
            pagination.getParams().put("machineName", request.getMachineName());
        }
        if (StringUtils.isNotBlank(request.getParamName())) {
            pagination.getParams().put("paramName", request.getParamName());
        }
        if (StringUtils.isNotBlank(request.getParamDesc())) {
            pagination.getParams().put("paramDesc", request.getParamDesc());
        }

        paramDAO.selectParamPage(pagination);
        response.getPagination().setPageSize(request.getPagination().getPageSize());
        response.getPagination().setPageNo(request.getPagination().getPageNo());
        response.getPagination().setTotal(pagination.getTotal());
        response.getPagination().setPageNum(pagination.getPageNum());
        for (QueryParamInfoBO record : pagination.getRecords()) {
            response.addRecord(QueryParamRecord.builder()
                            .paramId(record.getParamId())
                            .project(record.getProjectDesc() + "(" + record.getGroupId() + ":" + record.getArtifactId() + ":" + record.getVersion() + ")")
                            .environment(record.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(record.getEnvironmentType()).getDesc() + ")")
                            .machine(record.getMachineName())
                            .paramName(record.getParamName())
                            .paramVersion(record.getParamVersion())
                            .build()
            );
        }
        return response;
    }

    @Override
    public ListParamByMachineResponse listParamByMachine(ListParamByMachineRequest request) {
        ListParamByMachineResponse response = new ListParamByMachineResponse();
        List<ParamInfoEntity> paramEntities = paramDAO.selectAnd(ParamInfoEntity.builder().machineId(request.getMachineId()).paramStatus(ParamStatusEnum.NORMAL.getCode()).build());
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(request.getMachineId());
        for (ParamInfoEntity paramEntity : paramEntities) {
            //查询当前用户是否拥有权限
            int hasAuthority = authorityDAO.countAnd(AuthorityInfoEntity.builder()
                    .resourceType(ResourceTypeEnum.PARAM.getCode())
                    .resourceId(paramEntity.getParamId())
                    .userId(request.getLoginUserId())
                    .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                    .build());
            String paramValue = null;
            if (hasAuthority > 0) {
                paramValue = paramEntity.getParamValue();
            } else {
                paramValue = "您当前无权限查看！";
            }
            response.getParams().add(ListParamRecord.builder()
                    .paramName(paramEntity.getParamName())
                    .paramValue(paramValue)
                    .paramDataType(paramEntity.getParamDataType())
                    .paramEncrypt(paramEntity.getParamEncrypt())
                    .paramDynamic(paramEntity.getParamDynamic())
                    .paramVersion(paramEntity.getParamVersion())
                    .paramDesc(paramEntity.getParamDesc())
                    .build());
        }
        return response;
    }


    @Override
    public ExportParamResponse exportParam(ExportParamRequest request) {
        ExportParamResponse response = new ExportParamResponse();
        ProjectInfoEntity projectInfoEntity = projectDAO.selectByPrimaryKey(request.getProjectId());
        if (projectInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        List<EnvironmentInfoEntity> environmentInfoEntities = environmentDAO.selectAnd(EnvironmentInfoEntity.builder()
                .projectId(request.getProjectId())
                .environmentName(request.getEnvironmentName())
                .environmentStatus(EnvironmentStatusEnum.NORMAL.getCode())
                .build());
        if (environmentInfoEntities.isEmpty()) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        EnvironmentInfoEntity environmentInfoEntity = environmentInfoEntities.get(0);
        List<MachineInfoEntity> machineInfoEntities = machineDAO.selectAnd(MachineInfoEntity.builder()
                .projectId(request.getProjectId())
                .environmentId(environmentInfoEntity.getEnvironmentId())
                .machineName(request.getMachineName())
                .build());
        if (machineInfoEntities.isEmpty()) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        MachineInfoEntity machineInfoEntity = machineInfoEntities.get(0);
        List<ParamInfoEntity> paramInfoEntities = paramDAO.selectAnd(ParamInfoEntity.builder()
                .projectId(request.getProjectId())
                .environmentId(environmentInfoEntity.getEnvironmentId())
                .machineId(machineInfoEntity.getMachineId())
                .build());
        for (ParamInfoEntity paramInfoEntity : paramInfoEntities) {
            response.getParams().add(ExportParamRecord.builder()
                    .paramName(paramInfoEntity.getParamName())
                    .paramValue(paramInfoEntity.getParamValue())
                    .paramType(paramInfoEntity.getParamType())
                    .paramDataType(paramInfoEntity.getParamDataType())
                    .paramDesc(paramInfoEntity.getParamDesc())
                    .paramStatus(paramInfoEntity.getParamStatus())
                    .paramDynamic(paramInfoEntity.getParamDynamic())
                    .paramSystemProperties(paramInfoEntity.getParamSystemProperties())
                    .paramEncrypt(paramInfoEntity.getParamEncrypt())
                    .build());
        }
        return response;
    }

    @Override
    public ImportParamResponse importParam(ImportParamRequest request) {
        ImportParamResponse response = new ImportParamResponse();
        ProjectInfoEntity projectInfoEntity = projectDAO.selectByPrimaryKey(request.getProjectId());
        if (projectInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        List<EnvironmentInfoEntity> environmentInfoEntities = environmentDAO.selectAnd(EnvironmentInfoEntity.builder()
                .projectId(request.getProjectId())
                .environmentName(request.getEnvironmentName())
                .environmentStatus(EnvironmentStatusEnum.NORMAL.getCode())
                .build());
        if (environmentInfoEntities.isEmpty()) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        EnvironmentInfoEntity environmentInfoEntity = environmentInfoEntities.get(0);
        List<MachineInfoEntity> machineInfoEntities = machineDAO.selectAnd(MachineInfoEntity.builder()
                .projectId(request.getProjectId())
                .environmentId(environmentInfoEntity.getEnvironmentId())
                .machineName(request.getMachineName())
                .build());
        if (machineInfoEntities.isEmpty()) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        MachineInfoEntity machineInfoEntity = machineInfoEntities.get(0);
        //刷新机器的更新时间
        machineDAO.updateByPrimaryKeySelective(machineInfoEntity);
        for (ImportParamRecord record : request.getParams()) {
            ParamInfoEntity paramInfoEntity = ParamInfoEntity.builder()
                    .projectId(request.getProjectId())
                    .environmentId(environmentInfoEntity.getEnvironmentId())
                    .machineId(machineInfoEntity.getMachineId())
                    .paramName(record.getParamName())
                    .build();
            List<ParamInfoEntity> paramInfoEntities = paramDAO.selectAnd(paramInfoEntity);
            if (paramInfoEntities.isEmpty()) {
                paramInfoEntity.setParamValue(record.getParamValue());
                paramInfoEntity.setParamType(record.getParamType());
                paramInfoEntity.setParamDataType(record.getParamDataType());
                paramInfoEntity.setParamDesc(record.getParamDesc());
                paramInfoEntity.setParamStatus(record.getParamStatus());
                paramInfoEntity.setParamDynamic(record.getParamDynamic());
                paramInfoEntity.setParamSystemProperties(record.getParamSystemProperties());
                paramInfoEntity.setParamEncrypt(record.getParamEncrypt());
                paramDAO.insertSelective(paramInfoEntity);
            } else {
                paramDAO.updateByPrimaryKeySelective(ParamInfoEntity.builder()
                        .projectId(request.getProjectId())
                        .environmentId(environmentInfoEntity.getEnvironmentId())
                        .machineId(machineInfoEntity.getMachineId())
                        .paramName(record.getParamName())
                        .paramValue(record.getParamValue())
                        .paramType(record.getParamType())
                        .paramDataType(record.getParamDataType())
                        .paramDesc(record.getParamDesc())
                        .paramStatus(record.getParamStatus())
                        .paramDynamic(record.getParamDynamic())
                        .paramSystemProperties(record.getParamSystemProperties())
                        .paramEncrypt(record.getParamEncrypt())
                        .build());
            }
        }
        return response;
    }

    @Override
    public GrantParamResponse grant(GrantParamRequest request) {
        GrantParamResponse response = new GrantParamResponse();
        String user = request.getUser();
        String[] _strs = user.split("@");
        int count = authorityDAO.countAnd(AuthorityInfoEntity.builder()
                .resourceId(request.getParamId())
                .resourceType(ResourceTypeEnum.PARAM.getCode())
                .userId(Integer.valueOf(_strs[1]))
                .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                .build());
        if (count != 0) {
            response.updateResult(ConfigResponseCode.NO_DATA.getCode(),"已经对用户" + _strs[0] + "进行授权!");
            return response;
        }
        authorityDAO.insertSelective(AuthorityInfoEntity.builder()
                        .resourceType(1)
                        .resourceId(request.getParamId())
                        .userId(Integer.valueOf(_strs[1]))
                        .userName(_strs[0])
                        .createOperatorId(request.getLoginUserId())
                        .createOperatorName(request.getLoginUserName())
                        .authorityStatus(AuthorityStatusEnum.NORMAL.getCode())
                        .build()
        );
        return response;
    }
}
